home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C; tab-width: 4 -*- */
- /* pipes --- 3D selfbuiding pipe system */
-
- #if !defined( lint ) && !defined( SABER )
- static const char sccsid[] = "@(#)pipes.c 4.07 97/11/24 xlockmore";
-
- #endif
-
- /*-
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * This file is provided AS IS with no warranties of any kind. The author
- * shall have no liability with respect to the infringement of copyrights,
- * trade secrets or any patents by this file or any part thereof. In no
- * event will the author be liable for any lost revenue or profits or
- * other special, indirect and consequential damages.
- *
- * This program was inspired on a WindowsNT(R)'s screen saver. It was written
- * from scratch and it was not based on any other source code.
- *
- * ==========================================================================
- * The routine myElbow is derivated from the doughnut routine from the OpenGL
- * library (more especifically the Mesaaux library) written by Brian Paul.
- * ==========================================================================
- *
- * Thanks goes to Brian Paul for making it possible and inexpensive to use
- * OpenGL at home.
- *
- * Since I'm not a native English speaker, my apologies for any grammatical
- * mistake.
- *
- * My e-mail address is
- * m-vianna@usa.net
- * Marcelo F. Vianna (Apr-09-1997)
- *
- * Revision History:
- * 29-Apr-97: Factory equipment by Ed Mackey. Productive day today, eh?
- * 29-Apr-97: Less tight turns Jeff Epler <jepler@inetnebr.com>
- * 29-Apr-97: Efficiency speed-ups by Marcelo F. Vianna
- */
-
- /*-
- * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
- * otherwise caddr_t is not defined correctly
- */
-
- /*
- #include <X11/Intrinsic.h>
-
- #ifdef STANDALONE
- # define PROGCLASS "Pipes"
- # define HACK_INIT init_pipes
- # define HACK_DRAW draw_pipes
- # define pipes_opts xlockmore_opts
- # define DEFAULTS "*delay: 100 \n" \
- "*count: 2 \n" \
- "*cycles: 5 \n" \
- "*size: 500 \n" \
- "*fisheye: True \n" \
- "*tightturns: False \n" \
- "*rotatepipes: True \n" \
- "*noBuffer: True \n"
- # include "xlockmore.h"
- #else
- # include "xlock.h"
- #endif
-
- #ifdef USE_GL
-
- */
-
- #include <OpenGL/glu.h>
- #include "buildlwo.h"
-
- #define DEF_FACTORY "2"
- #define DEF_FISHEYE "True"
- #define DEF_TIGHTTURNS "False"
- #define DEF_ROTATEPIPES "True"
- #define NofSysTypes 3
- #define Bool int
-
- extern int NRAND_PIPES(int foo);
-
-
- static int factory;
- static Bool fisheye, tightturns, rotatepipes;
-
- /*
- static XrmOptionDescRec opts[] =
- {
- {"-factory", ".pipes.factory", XrmoptionSepArg, (caddr_t) NULL},
- {"-fisheye", ".pipes.fisheye", XrmoptionNoArg, (caddr_t) "on"},
- {"+fisheye", ".pipes.fisheye", XrmoptionNoArg, (caddr_t) "off"},
- {"-tightturns", ".pipes.tightturns", XrmoptionNoArg, (caddr_t) "on"},
- {"+tightturns", ".pipes.tightturns", XrmoptionNoArg, (caddr_t) "off"},
- {"-rotatepipes", ".pipes.rotatepipes", XrmoptionNoArg, (caddr_t) "on"},
- {"+rotatepipes", ".pipes.rotatepipes", XrmoptionNoArg, (caddr_t) "off"}
- };
- static argtype vars[] =
- {
- {(caddr_t *) & factory, "factory", "Factory", DEF_FACTORY, t_Int},
- {(caddr_t *) & fisheye, "fisheye", "Fisheye", DEF_FISHEYE, t_Bool},
- {(caddr_t *) & tightturns, "tightturns", "Tightturns", DEF_TIGHTTURNS, t_Bool},
- {(caddr_t *) & rotatepipes, "rotatepipes", "Rotatepipes", DEF_ROTATEPIPES, t_Bool}
- };
- static OptionStruct desc[] =
- {
- {"-factory num", "how much extra equipment in pipes (0 for none)"},
- {"-/+fisheye", "turn on/off zoomed-in view of pipes"},
- {"-/+tightturns", "turn on/off tight turns"},
- {"-/+rotatepipes", "turn on/off pipe system rotation per screenful"}
- };
-
- ModeSpecOpt pipes_opts =
- {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
-
- #ifdef USE_MODULES
- ModStruct pipes_description =
- {"pipes", "init_pipes", "draw_pipes", "release_pipes",
- #if defined( MESA ) && defined( SLOW )
- "draw_pipes",
- #else
- "change_pipes",
- #endif
- "change_pipes", NULL, &pipes_opts,
- 1000, 2, 5, 500, 4, 1.0, "",
- "Shows a selfbuilding pipe system", 0, NULL};
-
- #endif
-
- */
-
- #define Scale4Window 0.1
- #define Scale4Iconic 0.07
-
- #define one_third 0.3333333333333333333
-
- #define dirNone -1
- #define dirUP 0
- #define dirDOWN 1
- #define dirLEFT 2
- #define dirRIGHT 3
- #define dirNEAR 4
- #define dirFAR 5
-
- #define HCELLS 33
- #define VCELLS 25
- #define DEFINEDCOLORS 7
- #define elbowradius 0.5
-
- /*************************************************************************/
-
- GLint WindH, WindW;
- int Cells[HCELLS][VCELLS][HCELLS];
- int usedcolors[DEFINEDCOLORS];
- int directions[6];
- int ndirections;
- int nowdir, olddir;
- int system_number;
- int counter;
- int PX, PY, PZ;
- int number_of_systems;
- int system_type;
- int system_length;
- int turncounter;
- float *system_color;
- GLfloat initial_rotation;
- GLuint valve, bolts, betweenbolts, elbowbolts, elbowcoins;
- GLuint guagehead, guageface, guagedial, guageconnector;
- int isMono = 0;
- int isWireframe = 0;
-
-
- extern struct lwo LWO_BigValve, LWO_PipeBetweenBolts, LWO_Bolts3D;
- extern struct lwo LWO_GuageHead, LWO_GuageFace, LWO_GuageDial, LWO_GuageConnector;
- extern struct lwo LWO_ElbowBolts, LWO_ElbowCoins;
-
- static float pipe_shininess[] =
- {60.0};
- static float pipe_specular[] =
- {0.7, 0.7, 0.7, 1.0};
- static float ambient_pipe0[] =
- {0.4, 0.4, 0.4, 1.0};
- static float diffuse_pipe0[] =
- {1.0, 1.0, 1.0, 1.0};
- static float ambient_pipe1[] =
- {0.2, 0.2, 0.2, 1.0};
- static float diffuse_pipe1[] =
- {0.5, 0.5, 0.5, 1.0};
- static float position_pipe0[] =
- {1.0, 1.0, 1.0, 0.0};
- static float position_pipe1[] =
- {-1.0, -1.0, 1.0, 0.0};
- static float lmodel_ambient_pipe[] =
- {0.5, 0.5, 0.5, 1.0};
- static float lmodel_twoside_pipe[] =
- {GL_TRUE};
-
- static float MaterialRed[] =
- {0.7, 0.0, 0.0, 1.0};
- static float MaterialGreen[] =
- {0.1, 0.5, 0.2, 1.0};
- static float MaterialBlue[] =
- {0.0, 0.0, 0.7, 1.0};
- static float MaterialCyan[] =
- {0.2, 0.5, 0.7, 1.0};
- static float MaterialYellow[] =
- {0.7, 0.7, 0.0, 1.0};
- static float MaterialMagenta[] =
- {0.6, 0.2, 0.5, 1.0};
- static float MaterialWhite[] =
- {0.7, 0.7, 0.7, 1.0};
- static float MaterialGray[] =
- {0.2, 0.2, 0.2, 1.0};
-
- static void
- MakeTube(int direction)
- {
- float an;
- float SINan_3, COSan_3;
-
- /*dirUP = 00000000 */
- /*dirDOWN = 00000001 */
- /*dirLEFT = 00000010 */
- /*dirRIGHT = 00000011 */
- /*dirNEAR = 00000100 */
- /*dirFAR = 00000101 */
-
- if (!(direction & 4)) {
- glRotatef(90.0, (direction & 2) ? 0.0 : 1.0,
- (direction & 2) ? 1.0 : 0.0, 0.0);
- }
- glBegin(GL_QUAD_STRIP);
- for (an = 0.0; an <= 2.0 * M_PI; an += M_PI / 12.0) {
- glNormal3f((COSan_3 = cos(an) / 3.0), (SINan_3 = sin(an) / 3.0), 0.0);
- glVertex3f(COSan_3, SINan_3, one_third);
- glVertex3f(COSan_3, SINan_3, -one_third);
- }
- glEnd();
- }
-
- static void
- mySphere(float radius)
- {
- GLUquadricObj *quadObj;
-
- quadObj = gluNewQuadric();
- gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
- gluSphere(quadObj, radius, 16, 16);
- gluDeleteQuadric(quadObj);
- }
-
- static void
- myElbow(int bolted)
- {
- #define nsides 25
- #define rings 25
- #define r one_third
- #define R one_third
-
- int i, j;
- GLfloat p0[3], p1[3], p2[3], p3[3];
- GLfloat n0[3], n1[3], n2[3], n3[3];
- GLfloat COSphi, COSphi1, COStheta, COStheta1;
- GLfloat _SINtheta, _SINtheta1;
-
- for (i = 0; i <= rings / 4; i++) {
- GLfloat theta, theta1;
-
- theta = (GLfloat) i *2.0 * M_PI / rings;
-
- theta1 = (GLfloat) (i + 1) * 2.0 * M_PI / rings;
- for (j = 0; j < nsides; j++) {
- GLfloat phi, phi1;
-
- phi = (GLfloat) j *2.0 * M_PI / nsides;
-
- phi1 = (GLfloat) (j + 1) * 2.0 * M_PI / nsides;
-
- p0[0] = (COStheta = cos(theta)) * (R + r * (COSphi = cos(phi)));
- p0[1] = (_SINtheta = -sin(theta)) * (R + r * COSphi);
-
- p1[0] = (COStheta1 = cos(theta1)) * (R + r * COSphi);
- p1[1] = (_SINtheta1 = -sin(theta1)) * (R + r * COSphi);
-
- p2[0] = COStheta1 * (R + r * (COSphi1 = cos(phi1)));
- p2[1] = _SINtheta1 * (R + r * COSphi1);
-
- p3[0] = COStheta * (R + r * COSphi1);
- p3[1] = _SINtheta * (R + r * COSphi1);
-
- n0[0] = COStheta * COSphi;
- n0[1] = _SINtheta * COSphi;
-
- n1[0] = COStheta1 * COSphi;
- n1[1] = _SINtheta1 * COSphi;
-
- n2[0] = COStheta1 * COSphi1;
- n2[1] = _SINtheta1 * COSphi1;
-
- n3[0] = COStheta * COSphi1;
- n3[1] = _SINtheta * COSphi1;
-
- p0[2] = p1[2] = r * (n0[2] = n1[2] = sin(phi));
- p2[2] = p3[2] = r * (n2[2] = n3[2] = sin(phi1));
-
- glBegin(GL_QUADS);
- glNormal3fv(n3);
- glVertex3fv(p3);
- glNormal3fv(n2);
- glVertex3fv(p2);
- glNormal3fv(n1);
- glVertex3fv(p1);
- glNormal3fv(n0);
- glVertex3fv(p0);
- glEnd();
- }
- }
-
- if (factory > 0 && bolted) {
- /* Bolt the elbow onto the pipe system */
- glFrontFace(GL_CW);
- glPushMatrix();
- glRotatef(90.0, 0.0, 0.0, -1.0);
- glRotatef(90.0, 0.0, 1.0, 0.0);
- glTranslatef(0.0, one_third, one_third);
- glCallList(elbowcoins);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
- glCallList(elbowbolts);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, system_color);
- glPopMatrix();
- glFrontFace(GL_CCW);
- }
- #undef r
- #undef R
- #undef nsides
- #undef rings
- }
-
- static void
- FindNeighbors()
- {
-
- ndirections = 0;
- directions[dirUP] = (!Cells[PX][PY + 1][PZ]) ? 1 : 0;
- ndirections += directions[dirUP];
- directions[dirDOWN] = (!Cells[PX][PY - 1][PZ]) ? 1 : 0;
- ndirections += directions[dirDOWN];
- directions[dirLEFT] = (!Cells[PX - 1][PY][PZ]) ? 1 : 0;
- ndirections += directions[dirLEFT];
- directions[dirRIGHT] = (!Cells[PX + 1][PY][PZ]) ? 1 : 0;
- ndirections += directions[dirRIGHT];
- directions[dirFAR] = (!Cells[PX][PY][PZ - 1]) ? 1 : 0;
- ndirections += directions[dirFAR];
- directions[dirNEAR] = (!Cells[PX][PY][PZ + 1]) ? 1 : 0;
- ndirections += directions[dirNEAR];
- }
-
- static int
- SelectNeighbor()
- {
- int dirlist[6];
- int i, j;
-
- for (i = 0, j = 0; i < 6; i++) {
- if (directions[i]) {
- dirlist[j] = i;
- j++;
- }
- }
-
- return dirlist[NRAND_PIPES(ndirections)];
- }
-
- static void
- MakeValve(int newdir)
- {
- /* There is a glPopMatrix() right after this subroutine returns. */
- switch (newdir) {
- case dirUP:
- case dirDOWN:
- glRotatef(90.0, 1.0, 0.0, 0.0);
- glRotatef(NRAND_PIPES(3) * 90.0, 0.0, 0.0, 1.0);
- break;
- case dirLEFT:
- case dirRIGHT:
- glRotatef(90.0, 0.0, -1.0, 0.0);
- glRotatef((NRAND_PIPES(3) * 90.0) - 90.0, 0.0, 0.0, 1.0);
- break;
- case dirNEAR:
- case dirFAR:
- glRotatef(NRAND_PIPES(4) * 90.0, 0.0, 0.0, 1.0);
- break;
- }
- glFrontFace(GL_CW);
- glCallList(betweenbolts);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
- glCallList(bolts);
- if (!isMono) {
- if (system_color == MaterialRed) {
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, NRAND_PIPES(2) ? MaterialYellow : MaterialBlue);
- } else if (system_color == MaterialBlue) {
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, NRAND_PIPES(2) ? MaterialRed : MaterialYellow);
- } else if (system_color == MaterialYellow) {
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, NRAND_PIPES(2) ? MaterialBlue : MaterialRed);
- } else {
- switch ((NRAND_PIPES(3))) {
- case 0:
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed);
- break;
- case 1:
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialBlue);
- break;
- case 2:
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialYellow);
- }
- }
- }
- glRotatef((GLfloat) (NRAND_PIPES(90)), 1.0, 0.0, 0.0);
- glCallList(valve);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, system_color);
- glFrontFace(GL_CCW);
- }
-
- static int
- MakeGuage(int newdir)
- {
-
- /* Can't have a guage on a vertical pipe. */
- if ((newdir == dirUP) || (newdir == dirDOWN))
- return (0);
-
- /* Is there space above this pipe for a guage? */
- if (!directions[dirUP])
- return (0);
-
- /* Yes! Mark the space as used. */
- Cells[PX][PY + 1][PZ] = 1;
-
- glFrontFace(GL_CW);
- glPushMatrix();
- if ((newdir == dirLEFT) || (newdir == dirRIGHT))
- glRotatef(90.0, 0.0, 1.0, 0.0);
- glCallList(betweenbolts);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray);
- glCallList(bolts);
- glPopMatrix();
-
- glCallList(guageconnector);
- glPushMatrix();
- glTranslatef(0.0, 1.33333, 0.0);
- /* Do not change the above to 1 + ONE_THIRD, because */
- /* the object really is centered on 1.3333300000. */
- glRotatef(NRAND_PIPES(270) + 45.0, 0.0, 0.0, -1.0);
- /* Random rotation for the dial. I love it. */
- glCallList(guagedial);
- glPopMatrix();
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, system_color);
- glCallList(guagehead);
-
- /* GuageFace is drawn last, in case of low-res depth buffers. */
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialWhite);
- glCallList(guageface);
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, system_color);
- glFrontFace(GL_CCW);
-
- return (1);
- }
-
- static void
- MakeShape(int newdir)
- {
- switch (NRAND_PIPES(2)) {
- case 1:
- if (!MakeGuage(newdir))
- MakeTube(newdir);
- break;
- default:
- MakeValve(newdir);
- break;
- }
- }
-
- static void
- reshape_pipes(int width, int height)
- {
-
- glViewport(0, 0, WindW = (GLint) width, WindH = (GLint) height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- /*glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 15.0); */
- gluPerspective(65.0, (GLfloat) width / (GLfloat) height, 0.1, 20.0);
- glMatrixMode(GL_MODELVIEW);
- }
-
- static void
- pinit(int zera)
- {
- int X, Y, Z;
-
- glClearDepth(1.0);
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glColor3f(1.0, 1.0, 1.0);
-
- glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_pipe0);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_pipe0);
- glLightfv(GL_LIGHT0, GL_POSITION, position_pipe0);
- glLightfv(GL_LIGHT1, GL_AMBIENT, ambient_pipe1);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_pipe1);
- glLightfv(GL_LIGHT1, GL_POSITION, position_pipe1);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient_pipe);
- glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside_pipe);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_LIGHT1);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_NORMALIZE);
- glEnable(GL_CULL_FACE);
-
- glShadeModel(GL_SMOOTH);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, pipe_shininess);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pipe_specular);
-
- if (zera) {
- system_number = 1;
- glDrawBuffer(GL_FRONT_AND_BACK);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- (void) memset(Cells, 0, sizeof (Cells));
- for (X = 0; X < HCELLS; X++) {
- for (Y = 0; Y < VCELLS; Y++) {
- Cells[X][Y][0] = 1;
- Cells[X][Y][HCELLS - 1] = 1;
- Cells[0][Y][X] = 1;
- Cells[HCELLS - 1][Y][X] = 1;
- }
- }
- for (X = 0; X < HCELLS; X++) {
- for (Z = 0; Z < HCELLS; Z++) {
- Cells[X][0][Z] = 1;
- Cells[X][VCELLS - 1][Z] = 1;
- }
- }
- (void) memset(usedcolors, 0, sizeof (usedcolors));
- if ((initial_rotation += 10.0) > 45.0) {
- initial_rotation -= 90.0;
- }
- }
- counter = 0;
- turncounter = 0;
-
- if (!isMono) {
- int collist[DEFINEDCOLORS];
- int i, j, lower = 1000;
-
- /* Avoid repeating colors on the same screen unless necessary */
- for (i = 0; i < DEFINEDCOLORS; i++) {
- if (lower > usedcolors[i])
- lower = usedcolors[i];
- }
- for (i = 0, j = 0; i < DEFINEDCOLORS; i++) {
- if (usedcolors[i] == lower) {
- collist[j] = i;
- j++;
- }
- }
- i = collist[NRAND_PIPES(j)];
- usedcolors[i]++;
- switch (i) {
- case 0:
- system_color = MaterialRed;
- break;
- case 1:
- system_color = MaterialGreen;
- break;
- case 2:
- system_color = MaterialBlue;
- break;
- case 3:
- system_color = MaterialCyan;
- break;
- case 4:
- system_color = MaterialYellow;
- break;
- case 5:
- system_color = MaterialMagenta;
- break;
- case 6:
- system_color = MaterialWhite;
- break;
- }
- } else {
- system_color = MaterialGray;
- }
-
- do {
- PX = NRAND_PIPES((HCELLS - 1)) + 1;
- PY = NRAND_PIPES((VCELLS - 1)) + 1;
- PZ = NRAND_PIPES((HCELLS - 1)) + 1;
- } while (Cells[PX][PY][PZ] ||
- (Cells[PX + 1][PY][PZ] && Cells[PX - 1][PY][PZ] &&
- Cells[PX][PY + 1][PZ] && Cells[PX][PY - 1][PZ] &&
- Cells[PX][PY][PZ + 1] && Cells[PX][PY][PZ - 1]));
- Cells[PX][PY][PZ] = 1;
- olddir = dirNone;
-
- FindNeighbors();
-
- nowdir = SelectNeighbor();
- }
-
- void
- init_pipes()
- {
-
- reshape_pipes(WindW, WindH);
- if (rotatepipes)
- initial_rotation = NRAND_PIPES(180); /* jwz */
- else
- initial_rotation = -10.0;
- pinit(1);
-
- if (factory > 0) {
- valve = BuildLWO(isWireframe, &LWO_BigValve);
- bolts = BuildLWO(isWireframe, &LWO_Bolts3D);
- betweenbolts = BuildLWO(isWireframe, &LWO_PipeBetweenBolts);
-
- elbowbolts = BuildLWO(isWireframe, &LWO_ElbowBolts);
- elbowcoins = BuildLWO(isWireframe, &LWO_ElbowCoins);
-
- guagehead = BuildLWO(isWireframe, &LWO_GuageHead);
- guageface = BuildLWO(isWireframe, &LWO_GuageFace);
- guagedial = BuildLWO(isWireframe, &LWO_GuageDial);
- guageconnector = BuildLWO(isWireframe, &LWO_GuageConnector);
- }
- /* else they are all 0, thanks to calloc(). */
-
- system_type = NRAND_PIPES(NofSysTypes) + 1;
-
- number_of_systems = 5;
-
- system_length = 1000;
- }
-
- void
- draw_pipes()
- {
-
- int newdir;
- int OPX, OPY, OPZ;
-
- //glDrawBuffer(GL_FRONT);
- glDrawBuffer(GL_BACK);
- glPushMatrix();
-
- glTranslatef(0.0, 0.0, fisheye ? -3.8 : -4.8);
- if (rotatepipes)
- glRotatef(initial_rotation, 0.0, 1.0, 0.0);
-
- //glScalef(Scale4Iconic, Scale4Iconic, Scale4Iconic);
- glScalef(Scale4Window, Scale4Window, Scale4Window);
-
-
- FindNeighbors();
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, system_color);
-
- /* If it's the begining of a system, draw a sphere */
- if (olddir == dirNone) {
- glPushMatrix();
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0);
- mySphere(0.6);
- glPopMatrix();
- }
- /* Check for stop conditions */
- if (ndirections == 0 || counter > system_length) {
- glPushMatrix();
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0);
- /* Finish the system with another sphere */
- mySphere(0.6);
- glPopMatrix();
-
- /* If the maximum number of system was drawn, restart (clearing the screen), */
- /* else start a new system. */
- if (++system_number > number_of_systems) {
- (void) sleep(1);
- pinit( 1);
- } else {
- pinit(0);
- }
-
- glPopMatrix();
- //glFlush();
- return;
- }
- counter++;
- turncounter++;
-
- /* Do will the direction change? if so, determine the new one */
- newdir = nowdir;
- if (!directions[newdir]) { /* cannot proceed in the current direction */
- newdir = SelectNeighbor();
- } else {
- if (tightturns) {
- /* random change (20% chance) */
- if ((counter > 1) && (NRAND_PIPES(100) < 20)) {
- newdir = SelectNeighbor();
- }
- } else {
- /* Chance to turn increases after each length of pipe drawn */
- if ((counter > 1) && NRAND_PIPES(50) < NRAND_PIPES(turncounter + 1)) {
- newdir = SelectNeighbor();
- turncounter = 0;
- }
- }
- }
-
- /* Has the direction changed? */
- if (newdir == nowdir) {
- /* If not, draw the cell's center pipe */
- glPushMatrix();
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0);
- /* Chance of factory shape here, if enabled. */
- if ((counter > 1) && (NRAND_PIPES(100) < factory)) {
- MakeShape(newdir);
- } else {
- MakeTube(newdir);
- }
- glPopMatrix();
- //glFlush();
- } else {
- /* If so, draw the cell's center elbow/sphere */
- int sysT = system_type;
-
- if (sysT == NofSysTypes + 1) {
- sysT = ((system_number - 1) % NofSysTypes) + 1;
- }
- glPushMatrix();
-
- switch (sysT) {
- case 1:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0);
- mySphere(elbowradius);
- break;
- case 2:
- case 3:
- switch (nowdir) {
- case dirUP:
- switch (newdir) {
- case dirLEFT:
- glTranslatef((PX - 16) / 3.0 * 4.0 - (one_third), (PY - 12) / 3.0 * 4.0 - (one_third), (PZ - 16) / 3.0 * 4.0);
- glRotatef(180.0, 1.0, 0.0, 0.0);
- break;
- case dirRIGHT:
- glTranslatef((PX - 16) / 3.0 * 4.0 + (one_third), (PY - 12) / 3.0 * 4.0 - (one_third), (PZ - 16) / 3.0 * 4.0);
- glRotatef(180.0, 1.0, 0.0, 0.0);
- glRotatef(180.0, 0.0, 1.0, 0.0);
- break;
- case dirFAR:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0 - (one_third), (PZ - 16) / 3.0 * 4.0 - (one_third));
- glRotatef(90.0, 0.0, 1.0, 0.0);
- glRotatef(180.0, 0.0, 0.0, 1.0);
- break;
- case dirNEAR:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0 - (one_third), (PZ - 16) / 3.0 * 4.0 + (one_third));
- glRotatef(90.0, 0.0, 1.0, 0.0);
- glRotatef(180.0, 1.0, 0.0, 0.0);
- break;
- }
- break;
- case dirDOWN:
- switch (newdir) {
- case dirLEFT:
- glTranslatef((PX - 16) / 3.0 * 4.0 - (one_third), (PY - 12) / 3.0 * 4.0 + (one_third), (PZ - 16) / 3.0 * 4.0);
- break;
- case dirRIGHT:
- glTranslatef((PX - 16) / 3.0 * 4.0 + (one_third), (PY - 12) / 3.0 * 4.0 + (one_third), (PZ - 16) / 3.0 * 4.0);
- glRotatef(180.0, 0.0, 1.0, 0.0);
- break;
- case dirFAR:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0 + (one_third), (PZ - 16) / 3.0 * 4.0 - (one_third));
- glRotatef(270.0, 0.0, 1.0, 0.0);
- break;
- case dirNEAR:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0 + (one_third), (PZ - 16) / 3.0 * 4.0 + (one_third));
- glRotatef(90.0, 0.0, 1.0, 0.0);
- break;
- }
- break;
- case dirLEFT:
- switch (newdir) {
- case dirUP:
- glTranslatef((PX - 16) / 3.0 * 4.0 + (one_third), (PY - 12) / 3.0 * 4.0 + (one_third), (PZ - 16) / 3.0 * 4.0);
- glRotatef(180.0, 0.0, 1.0, 0.0);
- break;
- case dirDOWN:
- glTranslatef((PX - 16) / 3.0 * 4.0 + (one_third), (PY - 12) / 3.0 * 4.0 - (one_third), (PZ - 16) / 3.0 * 4.0);
- glRotatef(180.0, 1.0, 0.0, 0.0);
- glRotatef(180.0, 0.0, 1.0, 0.0);
- break;
- case dirFAR:
- glTranslatef((PX - 16) / 3.0 * 4.0 + (one_third), (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0 - (one_third));
- glRotatef(270.0, 1.0, 0.0, 0.0);
- glRotatef(180.0, 0.0, 1.0, 0.0);
- break;
- case dirNEAR:
- glTranslatef((PX - 16) / 3.0 * 4.0 + (one_third), (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0 + (one_third));
- glRotatef(270.0, 1.0, 0.0, 0.0);
- glRotatef(180.0, 0.0, 0.0, 1.0);
- break;
- }
- break;
- case dirRIGHT:
- switch (newdir) {
- case dirUP:
- glTranslatef((PX - 16) / 3.0 * 4.0 - (one_third), (PY - 12) / 3.0 * 4.0 + (one_third), (PZ - 16) / 3.0 * 4.0);
- break;
- case dirDOWN:
- glTranslatef((PX - 16) / 3.0 * 4.0 - (one_third), (PY - 12) / 3.0 * 4.0 - (one_third), (PZ - 16) / 3.0 * 4.0);
- glRotatef(180.0, 1.0, 0.0, 0.0);
- break;
- case dirFAR:
- glTranslatef((PX - 16) / 3.0 * 4.0 - (one_third), (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0 - (one_third));
- glRotatef(270.0, 1.0, 0.0, 0.0);
- break;
- case dirNEAR:
- glTranslatef((PX - 16) / 3.0 * 4.0 - (one_third), (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0 + (one_third));
- glRotatef(90.0, 1.0, 0.0, 0.0);
- break;
- }
- break;
- case dirNEAR:
- switch (newdir) {
- case dirLEFT:
- glTranslatef((PX - 16) / 3.0 * 4.0 - (one_third), (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0 - (one_third));
- glRotatef(270.0, 1.0, 0.0, 0.0);
- break;
- case dirRIGHT:
- glTranslatef((PX - 16) / 3.0 * 4.0 + (one_third), (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0 - (one_third));
- glRotatef(270.0, 1.0, 0.0, 0.0);
- glRotatef(180.0, 0.0, 1.0, 0.0);
- break;
- case dirUP:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0 + (one_third), (PZ - 16) / 3.0 * 4.0 - (one_third));
- glRotatef(270.0, 0.0, 1.0, 0.0);
- break;
- case dirDOWN:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0 - (one_third), (PZ - 16) / 3.0 * 4.0 - (one_third));
- glRotatef(90.0, 0.0, 1.0, 0.0);
- glRotatef(180.0, 0.0, 0.0, 1.0);
- break;
- }
- break;
- case dirFAR:
- switch (newdir) {
- case dirUP:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0 + (one_third), (PZ - 16) / 3.0 * 4.0 + (one_third));
- glRotatef(90.0, 0.0, 1.0, 0.0);
- break;
- case dirDOWN:
- glTranslatef((PX - 16) / 3.0 * 4.0, (PY - 12) / 3.0 * 4.0 - (one_third), (PZ - 16) / 3.0 * 4.0 + (one_third));
- glRotatef(90.0, 0.0, 1.0, 0.0);
- glRotatef(180.0, 1.0, 0.0, 0.0);
- break;
- case dirLEFT:
- glTranslatef((PX - 16) / 3.0 * 4.0 - (one_third), (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0 + (one_third));
- glRotatef(90.0, 1.0, 0.0, 0.0);
- break;
- case dirRIGHT:
- glTranslatef((PX - 16) / 3.0 * 4.0 + (one_third), (PY - 12) / 3.0 * 4.0, (PZ - 16) / 3.0 * 4.0 + (one_third));
- glRotatef(270.0, 1.0, 0.0, 0.0);
- glRotatef(180.0, 0.0, 0.0, 1.0);
- break;
- }
- break;
- }
- myElbow((sysT == 2));
- break;
- }
- glPopMatrix();
- }
-
- OPX = PX;
- OPY = PY;
- OPZ = PZ;
- olddir = nowdir;
- nowdir = newdir;
- switch (nowdir) {
- case dirUP:
- PY++;
- break;
- case dirDOWN:
- PY--;
- break;
- case dirLEFT:
- PX--;
- break;
- case dirRIGHT:
- PX++;
- break;
- case dirNEAR:
- PZ++;
- break;
- case dirFAR:
- PZ--;
- break;
- }
- Cells[PX][PY][PZ] = 1;
-
- /* Cells'face pipe */
- glTranslatef(((PX + OPX) / 2.0 - 16) / 3.0 * 4.0, ((PY + OPY) / 2.0 - 12) / 3.0 * 4.0, ((PZ + OPZ) / 2.0 - 16) / 3.0 * 4.0);
- MakeTube(newdir);
-
- glPopMatrix();
-
- glFlush();
-
- }
-
- void
- change_pipes()
- {
-
- pinit(1);
- }
-
- void
- release_pipes()
- {
-
- /* Display lists MUST be freed while their glXContext is current. */
-
- if (valve)
- glDeleteLists(valve, 1);
- if (bolts)
- glDeleteLists(bolts, 1);
- if (betweenbolts)
- glDeleteLists(betweenbolts, 1);
-
- if (elbowbolts)
- glDeleteLists(elbowbolts, 1);
- if (elbowcoins)
- glDeleteLists(elbowcoins, 1);
-
- if (guagehead)
- glDeleteLists(guagehead, 1);
- if (guageface)
- glDeleteLists(guageface, 1);
- if (guagedial)
- glDeleteLists(guagedial, 1);
- if (guageconnector)
- glDeleteLists(guageconnector, 1);
-
- }